package com.highspeed.bdk.controller.security.user;

import com.highspeed.bdk.MainApplication;
import com.highspeed.bdk.bean.entity.security.Role;
import com.highspeed.bdk.bean.entity.security.User;
import com.highspeed.bdk.service.security.role.IRoleService;
import com.highspeed.bdk.service.security.user.IUserService;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {MainApplication.class})
@AutoConfigureMockMvc
@Transactional
@WithMockUser(username = "admin", roles = {"USER", "ADMIN", "abc"})
public class UserControllerTester {

    @Autowired
    private MockMvc mvc;
    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;
    private User user;
    private List<User> users;

    @Before
    public void before() throws Exception {

        Role role = new Role();
        role.setName("rolename");
        role.setCreator("SYSTEM");
        Role role1 = new Role();
        role1.setName("rolename1");
        role1.setCreator("SYSTEM");


        role = roleService.save(role);
        Assert.assertNotNull(role);
        Assert.assertNotNull(role.getId());

        role1 = roleService.save(role1);
        Assert.assertNotNull(role1);
        Assert.assertNotNull(role1.getId());

        user = new User();
        user.setPhone("phone1");
        user.setName("username");
        user.setPassword("password");
        user.setUsername("username");
        user.setCreator("SYSTEM1");
        user.setAccountExpiringDate(new Date());
        user.setCredentialsExpiringDate(new Date());
        user.setLocked(true);
        user.getRoles().add(role);


        user = userService.save(user);
        Assert.assertNotNull(user);
        Assert.assertNotNull(user.getId());
        Thread.sleep(20);

        users = new ArrayList<User>(0);
        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setPhone("phone");
            user.setName("name" + i);
            user.setPassword("password");
            user.setUsername("username" + i);
            user.setCreator("SYSTEM");
            user.setAccountExpiringDate(new Date());
            user.setCredentialsExpiringDate(new Date());
            user.setLocked(false);
            user.getRoles().add(role);
            user.getRoles().add(role1);
            users.add(user);
            Thread.sleep(10);
        }
        users = userService.save(users);
        Assert.assertNotNull(users);
        Assert.assertEquals(users.size(), 10);
    }

    @Test
    public void save() throws Exception {
        String id = UUID.randomUUID().toString();
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("entity.id", id);
        params.add("entity.name", "chenjunxi");
        params.add("entity.locked", "false");
        params.add("entity.phone", "phone");
        params.add("entity.creator", "SYSTEM");
        params.add("entity.accountExpiringDate", "2017/01/01");
        params.add("entity.credentialsExpiringDate", "2017/01/01");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/save");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.name", Matchers.is("chenjunxi")));
    }

    @Test
    public void getById() throws Exception {

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/get_by_id");
        builder.param("id", user.getId());
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.id", Matchers.is(user.getId())));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.roles[0].name", Matchers.is(user.getRoles().get(0).getName())));

    }

    @Test
    public void query() throws Exception {
        String id = UUID.randomUUID().toString();
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.name_like", user.getName());
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);
        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].name", Matchers.is(user.getName())));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].roles[0].name", Matchers.is(user.getRoles().get(0).getName())));

        //非json数据的情况下可以返回ViewAndModel
        // MvcResult result = resultActions.andReturn();
    }

    @Test
    public void queryEnabled() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.locked", "true");
        params.add("pageable.page", "0");
        params.add("pageable.size", "2");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(1)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(1)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].id", Matchers.is(user.getId())));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].name", Matchers.is(user.getName())));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].roles[*].name", Matchers.containsInAnyOrder(user.getRoles().get(0).getName())));
    }

    @Test
    public void queryNonEnabled() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.locked_ne", "true");
        params.add("params.username_like", "username");
        params.add("pageable.page", "0");
        params.add("pageable.size", "20");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(10)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(10)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].id", Matchers.is(users.get(0).getId())));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].name", Matchers.is(users.get(0).getName())));
    }

    @Test
    public void queryByPageable() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.name_:l:", "name");
        params.add("params.creator_ne", "q");
        params.add("pageable.page", "0");
        params.add("pageable.size", "2");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(11)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(2)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].id", Matchers.is(user.getId())));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].name", Matchers.is(user.getName())));

        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].roles[*].name", Matchers.containsInAnyOrder(user.getRoles().get(0).getName())));


        //非json数据的情况下可以返回ViewAndModel
        // MvcResult result = resultActions.andReturn();
    }

    @Test
    public void queryByRole() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.roles.name_eq", "rolename");
        params.add("pageable.page", "0");
        params.add("pageable.size", "999");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(11)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(11)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].id", Matchers.is(user.getId())));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].name", Matchers.is(user.getName())));

        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data[0].roles[*].name", Matchers.containsInAnyOrder(user.getRoles().get(0).getName())));


        //非json数据的情况下可以返回ViewAndModel
        // MvcResult result = resultActions.andReturn();
    }


    @Test
    public void queryEmptyParam() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.username_like", "username");
        params.add("params.roles.name_isnull", "");
        params.add("pageable.page", "0");
        params.add("pageable.size", "2");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(0)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(0)));

        //非json数据的情况下可以返回ViewAndModel
        // MvcResult result = resultActions.andReturn();
    }

    @Test
    public void queryByNoDistinct() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.roles.name_like", "rolename");
        params.add("pageable.page", "0");
        params.add("pageable.size", "999");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(21)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(21)));

        //非json数据的情况下可以返回ViewAndModel
        // MvcResult result = resultActions.andReturn();
    }

    @Test
    public void queryByDistinct() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.roles.name_like", "rolename");
        params.add("pageable.page", "0");
        params.add("pageable.size", "999");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query_distinct");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(11)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(11)));

        //非json数据的情况下可以返回ViewAndModel
        // MvcResult result = resultActions.andReturn();
    }

    @Test
    public void queryOr() throws Exception {
        LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("params.name_eq", "name1");
        params.add("params.phone_eq_or", "phone1");
        params.add("pageable.page", "0");
        params.add("pageable.size", "999");
        params.add("pageable.sort", "[{\"direction\":\"ASC\",\"property\":\"cdt\"}]");

        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/management/security/user/query");
        builder.params(params);
        builder.accept(MediaType.APPLICATION_JSON_UTF8);

        ResultActions resultActions = this.mvc.perform(builder);

        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
        resultActions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8));
        //打印信息
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.success", Matchers.is(true)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.total", Matchers.is(2)));
        resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.data.length()", Matchers.is(2)));

        //非json数据的情况下可以返回ViewAndModel
        // MvcResult result = resultActions.andReturn();
    }
}
